﻿using GN.Pay.Utils;
using GN.Pay.Utils.Security;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace GN.Pay.TradeChannel.WeiXin.Request
{
    [Serializable]
    public abstract class AServiceRequest : AService
    {
        /// <summary>
        /// 
        /// </summary>
        protected AServiceRequest()
        {
            this.Nonce_str = Guid.NewGuid().ToString("N").ToUpperInvariant();
            this.Sign_type = "MD5";
        }       

        /// <summary>
        ///    签名 sign    必填 String(32)  C380BEC2BFD727A4B6845133519F3AD6 签名，详见签名生成算法
        /// </summary>
        public string Sign { get; set; }

        /// <summary>
        /// 签名类型	sign_type	否	String(32)	HMAC-SHA256	签名类型，目前支持HMAC-SHA256和MD5，默认为MD5
        /// </summary>
        public string Sign_type { get; set; }

        /// <summary>
        /// 随机字符串，不长于32位
        /// </summary>
        public string Nonce_str { get; private set; }
        
        protected virtual bool IsAddSignType()
        {
            return true;
        }

        protected SignDictionary BuildSignDictionary(ITradeChannel channel,
          WeiXinConfigure config, params string[] removeKeys)
        {
            this.Sign_type = "MD5";
            var dic = this.GetSignDictionary(StringComparer.InvariantCultureIgnoreCase);
            if (!IsAddSignType())
            {
                dic.Remove("Sign_type");
            }
            Dictionary<string, string> removeItems = new Dictionary<string, string>();
            if (removeKeys != null)
            {
                foreach (var key in removeKeys)
                {
                    string value;
                    if (key != null && dic.TryGetValue(key, out value))
                    {
                        dic.Remove(key);
                        removeItems[key] = value;
                    }
                }
            }
            string content = dic.UrlLinkString(k =>
            {
                return k.ToLower();
            }, null) + "&key=" + config.ConfigureInfo.Key;
            if (string.IsNullOrWhiteSpace(content))
            {
                channel.ThrowChannelValidationException("待签名内容为null或空白字符");
            }
            this.Sign = Md5Utils.Sign(content, config.Encoding).ToUpperInvariant();
            if (removeItems.Count > 0)
            {
                foreach (var item in removeItems)
                {
                    dic[item.Key] = item.Value;
                }
            }
            dic["sign"] = Sign;
            if (!IsAddSignType())
            {
                dic.Remove("Sign_type");
            }
            return dic;
        }

        /// <summary>
        /// 生成签名参数
        /// </summary>
        /// <param name="removeKeys">需移除的参数，即不能参与签名的参数</param>
        /// <returns></returns>
        protected string BuildSignXmlParam(ITradeChannel channel,
            WeiXinConfigure config, params string[] removeKeys)
        {
            var dic = this.BuildSignDictionary(channel, config, removeKeys);
            string param = WeiXinUtils.ParseXML(dic);
            return param;
        }

       
    }
}
